#include "edit.h"

#include "bt.h"
#include "oled.h"
#include "sel.h"
#include "ws2812.h"

#undef Handler
#define Handler Edit_HandleTypeDef*

#undef handler
#define handler (**(Edit_HandleTypeDef**)&handle)

void Edit_Init(void* handle, uint8_t x, uint8_t y, uint8_t mode) {
  Bt_Init(Edit_M_L, NULL, NULL, Edit_M_O,    // M
          Edit_U_LJ, NULL, Edit_U_LJ, NULL,  // U
          Edit_D_LJ, NULL, Edit_D_LJ, NULL,  // D
          NULL, NULL, Edit_L_J, NULL,        // L
          NULL, NULL, Edit_R_J, NULL,        // R
          50);

  handler.outo = 0;
  handler.grb = EDIT_BEGiN;
  handler.save = 0;
  handler.mode = mode;
  handler.x = x;
  handler.y = y;
  turn = 0xFF;
  Edit_Show(handle);
  turn = 0x00;
  while (hbt.bu & BU_M) Bt_Update();
}
void Edit_Show(void* handle) {
  switch (handler.grb) {
    case EDIT_G:
      Oled_ShowNumSmall(56, 4, hws.matrix.color[handler.x][handler.y][0], 3);
      break;
    case EDIT_R:
      Oled_ShowNumSmall(80, 4, hws.matrix.color[handler.x][handler.y][1], 3);
      break;
    case EDIT_B:
      Oled_ShowNumSmall(104, 4, hws.matrix.color[handler.x][handler.y][2], 3);
      break;
  }
}
void Edit_Cast(void* handle) {
  switch (handler.mode) {
    case SEL_POINT:
      break;
    case SEL_LINE:
      for (uint8_t i = 0; i < 32; i++) {
        hws.matrix.color[i][handler.y][0] =
            hws.matrix.color[handler.x][handler.y][0];
        hws.matrix.color[i][handler.y][1] =
            hws.matrix.color[handler.x][handler.y][1];
        hws.matrix.color[i][handler.y][2] =
            hws.matrix.color[handler.x][handler.y][2];
      }
      break;
    case SEL_RECT:
      for (uint8_t j = 0; j < 8; j++) {
        hws.matrix.color[handler.x][j][0] =
            hws.matrix.color[handler.x][handler.y][0];
        hws.matrix.color[handler.x][j][1] =
            hws.matrix.color[handler.x][handler.y][1];
        hws.matrix.color[handler.x][j][2] =
            hws.matrix.color[handler.x][handler.y][2];
      }
      break;
    case SEL_FILL:
      for (uint8_t i = 0; i < 32; i++) {
        for (uint8_t j = 0; j < 8; j++) {
          hws.matrix.color[i][j][0] = hws.matrix.color[handler.x][handler.y][0];
          hws.matrix.color[i][j][1] = hws.matrix.color[handler.x][handler.y][1];
          hws.matrix.color[i][j][2] = hws.matrix.color[handler.x][handler.y][2];
        }
      }
  }
}
void Edit_Run(void* handle) {
  while (1) {
    Bt_Update();
    Bt_Run(handle);
    if (handler.outo) {
      return;
    }
  }
}

void Edit_M_L(void* handle) { handler.outo = 1; }
void Edit_M_O(void* handle) {
  handler.outo = 1;
  handler.save = 1;
}

void Edit_U_LJ(void* handle) {
  if (hws.matrix.color[handler.x][handler.y][handler.grb] < 15)
    hws.matrix.color[handler.x][handler.y][handler.grb]++;
  else
    hws.matrix.color[handler.x][handler.y][handler.grb] = 0;
  Edit_Cast(handle);
  turn = 0xFF;
  Edit_Show(handle);
  turn = 0x00;
  Ws_Load(hws.matrix.color);
  Ws_Draw();
}

void Edit_D_LJ(void* handle) {
  if (hws.matrix.color[handler.x][handler.y][handler.grb] > 0)
    hws.matrix.color[handler.x][handler.y][handler.grb]--;
  else
    hws.matrix.color[handler.x][handler.y][handler.grb] = 15;
  Edit_Cast(handle);
  turn = 0xFF;
  Edit_Show(handle);
  turn = 0x00;
  Ws_Load(hws.matrix.color);
  Ws_Draw();
}

void Edit_L_J(void* handle) {
  Edit_Show(handle);
  if (handler.grb > EDIT_BEGiN)
    handler.grb--;
  else
    handler.grb = EDIT_END;
  turn = 0xFF;
  Edit_Show(handle);
  turn = 0x00;
}
void Edit_R_J(void* handle) {
  Edit_Show(handle);
  if (handler.grb < EDIT_END)
    handler.grb++;
  else
    handler.grb = EDIT_BEGiN;
  turn = 0xFF;
  Edit_Show(handle);
  turn = 0x00;
}
